package com.easylive.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.easylive.entity.component.RedisComponent;
import com.easylive.entity.constants.Constants;
import com.easylive.entity.enums.StatisticsTypeEnum;
import com.easylive.entity.enums.UserActionTypeEnum;
import com.easylive.entity.po.UserFocus;
import com.easylive.entity.po.UserInfo;
import com.easylive.entity.po.VideoInfo;
import com.easylive.entity.query.*;
import com.easylive.mappers.UserFocusMapper;
import com.easylive.mappers.UserInfoMapper;
import com.easylive.mappers.VideoInfoMapper;
import com.easylive.utils.DateUtil;
import org.springframework.stereotype.Service;

import com.easylive.entity.enums.PageSize;
import com.easylive.entity.po.StatisticsInfo;
import com.easylive.entity.vo.PaginationResultVO;
import com.easylive.mappers.StatisticsInfoMapper;
import com.easylive.service.StatisticsInfoService;
import com.easylive.utils.StringTools;


/**
 * 数据统计 业务接口实现
 */
@Service("statisticsInfoService")
public class StatisticsInfoServiceImpl implements StatisticsInfoService {

	@Resource
	private StatisticsInfoMapper<StatisticsInfo, StatisticsInfoQuery> statisticsInfoMapper;

	@Resource
	private RedisComponent redisComponent;

	@Resource
	private VideoInfoMapper<VideoInfo, VideoInfoQuery> videoInfoMapper;

	@Resource
	private UserFocusMapper<UserFocus, UserFocusQuery> userFocusMapper;

	@Resource
	private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<StatisticsInfo> findListByParam(StatisticsInfoQuery param) {
		return this.statisticsInfoMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(StatisticsInfoQuery param) {
		return this.statisticsInfoMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<StatisticsInfo> findListByPage(StatisticsInfoQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<StatisticsInfo> list = this.findListByParam(param);
		PaginationResultVO<StatisticsInfo> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(StatisticsInfo bean) {
		return this.statisticsInfoMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<StatisticsInfo> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.statisticsInfoMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<StatisticsInfo> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.statisticsInfoMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(StatisticsInfo bean, StatisticsInfoQuery param) {
		StringTools.checkParam(param);
		return this.statisticsInfoMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(StatisticsInfoQuery param) {
		StringTools.checkParam(param);
		return this.statisticsInfoMapper.deleteByParam(param);
	}

	/**
	 * 根据StatisticsDateAndUserIdAndDataType获取对象
	 */
	@Override
	public StatisticsInfo getStatisticsInfoByStatisticsDateAndUserIdAndDataType(String statisticsDate, String userId, Integer dataType) {
		return this.statisticsInfoMapper.selectByStatisticsDateAndUserIdAndDataType(statisticsDate, userId, dataType);
	}

	/**
	 * 根据StatisticsDateAndUserIdAndDataType修改
	 */
	@Override
	public Integer updateStatisticsInfoByStatisticsDateAndUserIdAndDataType(StatisticsInfo bean, String statisticsDate, String userId, Integer dataType) {
		return this.statisticsInfoMapper.updateByStatisticsDateAndUserIdAndDataType(bean, statisticsDate, userId, dataType);
	}

	/**
	 * 根据StatisticsDateAndUserIdAndDataType删除
	 */
	@Override
	public Integer deleteStatisticsInfoByStatisticsDateAndUserIdAndDataType(String statisticsDate, String userId, Integer dataType) {
		return this.statisticsInfoMapper.deleteByStatisticsDateAndUserIdAndDataType(statisticsDate, userId, dataType);
	}

	@Override
	public void statisticData() {
		List<StatisticsInfo> statisticsInfoList = new ArrayList<>();

		// 整点执行的，需要获取前一天
		final String statisticDate = DateUtil.getBeforeDate(Constants.ONE);

		/**
		 * 统计播放量
		 */
		Map<String, Integer> videoPlayCount = redisComponent.getVideoPlayCount(statisticDate);

		// easylive:video:playcount:2024-12-26:IBhaQLBMyY
		List<String> playVideoKeys = new ArrayList<>(videoPlayCount.keySet());
		playVideoKeys = playVideoKeys.stream().map(item -> item.substring(item.lastIndexOf(":") + 1)).collect(Collectors.toList());

		VideoInfoQuery videoInfoQuery = new VideoInfoQuery();
		// 截取获取到的videoId
		videoInfoQuery.setVideoIds(playVideoKeys);

		// 从数据库中查询视频信息
		List<VideoInfo> videoInfoList = videoInfoMapper.selectList(videoInfoQuery);

		// 先按照userId分组，然后将当前userId上所有视频的播放量加起来
		Map<String, Integer> videoCountMap = videoInfoList.stream().collect(Collectors.groupingBy(VideoInfo::getUserId,
				Collectors.summingInt(item -> videoPlayCount.get(Constants.REDIS_KEY_VIDEO_PLAY_COUNT + statisticDate + ":" + item.getVideoId()))));

		// 此时得到的map，key是userId，value是该用户前一天所有视频的播放量总和
		videoCountMap.forEach((k, v) -> {
			StatisticsInfo statisticsInfo = new StatisticsInfo();
			statisticsInfo.setStatisticsDate(statisticDate);
			statisticsInfo.setUserId(k);
			statisticsInfo.setStatisticsCount(v);
			statisticsInfo.setDataType(StatisticsTypeEnum.PLAY.getType());
			statisticsInfoList.add(statisticsInfo);
		});

		/**
		 * 统计粉丝数
		 */
		List<StatisticsInfo> fansStatisticsInfoList = statisticsInfoMapper.selectStatisticsFans(statisticDate);
		fansStatisticsInfoList.forEach(statisticsInfo -> {
			statisticsInfo.setStatisticsDate(statisticDate);
			statisticsInfo.setDataType(StatisticsTypeEnum.FANS.getType());
		});
		statisticsInfoList.addAll(fansStatisticsInfoList);

		/**
		 * 统计评论数
		 */
		List<StatisticsInfo> commentsStatisticsInfoList = statisticsInfoMapper.selectStatisticsComments(statisticDate);
		commentsStatisticsInfoList.forEach(statisticsInfo -> {
			statisticsInfo.setStatisticsDate(statisticDate);
			statisticsInfo.setDataType(StatisticsTypeEnum.COMMENTS.getType());
		});
		statisticsInfoList.addAll(commentsStatisticsInfoList);

		/**
		 * 统计点赞数
		 */
		List<StatisticsInfo> likesStatisticsInfoList = statisticsInfoMapper.selectStatisticsAction(statisticDate, UserActionTypeEnum.VIDEO_LIKE.getType());
		likesStatisticsInfoList.forEach(statisticsInfo -> {
			statisticsInfo.setStatisticsDate(statisticDate);
			statisticsInfo.setDataType(StatisticsTypeEnum.LIKES.getType());
		});
		statisticsInfoList.addAll(likesStatisticsInfoList);

		/**
		 * 统计收藏数
		 */
		List<StatisticsInfo> collectionsStatisticsInfoList = statisticsInfoMapper.selectStatisticsAction(statisticDate, UserActionTypeEnum.VIDEO_COLLECT.getType());
		collectionsStatisticsInfoList.forEach(statisticsInfo -> {
			statisticsInfo.setStatisticsDate(statisticDate);
			statisticsInfo.setDataType(StatisticsTypeEnum.COLLECTIONS.getType());
		});
		statisticsInfoList.addAll(collectionsStatisticsInfoList);

		/**
		 * 统计投币数
		 */
		List<StatisticsInfo> coinsStatisticsInfoList = statisticsInfoMapper.selectStatisticsAction(statisticDate, UserActionTypeEnum.VIDEO_COIN.getType());
		coinsStatisticsInfoList.forEach(statisticsInfo -> {
			statisticsInfo.setStatisticsDate(statisticDate);
			statisticsInfo.setDataType(StatisticsTypeEnum.COIN.getType());
		});
		statisticsInfoList.addAll(coinsStatisticsInfoList);

		/**
		 * 统计弹幕数
		 */
		List<StatisticsInfo> danmusStatisticsInfoList = statisticsInfoMapper.selectStatisticsDanmus(statisticDate);
		danmusStatisticsInfoList.forEach(statisticsInfo -> {
			statisticsInfo.setStatisticsDate(statisticDate);
			statisticsInfo.setDataType(StatisticsTypeEnum.DANMU.getType());
		});
		statisticsInfoList.addAll(danmusStatisticsInfoList);

		statisticsInfoMapper.insertBatch(statisticsInfoList);
	}

	@Override
	public Map<String, Integer> getStatisticsInfoActualTime(String userId) {
		Map<String, Integer> resultMap = statisticsInfoMapper.selectTotalCountInfo(userId);
		// 如果是用户的，就查询用户的，如果是管理员，就查所有的
		if (!StringTools.isEmpty(userId)) {
			// 查询fansCount
			resultMap.put("fansCount", userFocusMapper.selectFansCount(userId));
		} else {
			resultMap.put("userCount", userInfoMapper.selectCount(new UserInfoQuery()));
		}
		return resultMap;
	}
}